#include "TaskQueue.h"
#include <iostream>

using std::cout;
using std::endl;


TaskQueue::TaskQueue(size_t capa)
: _capacity(capa)
, _que()
, _mutex()
, _notEmpty()
, _notFull()
, _wakeFlag(true)
{
    
}

TaskQueue::~TaskQueue(){}

//生产
void TaskQueue::push(ElemType &&taskcb)
{
    unique_lock<mutex> ul(_mutex);
    while(full())//判满
    {
        _notFull.wait(ul);//等待队列非满
    }
    
    //插入
    _que.push(std::move(taskcb));

    _notEmpty.notify_one();//队列非空：唤醒消费者
}

//消费
ElemType TaskQueue::pop()
{
    unique_lock<mutex> ul(_mutex);
    while(empty() && _wakeFlag)
    {
        _notEmpty.wait(ul);
    }

    //队列非空返回队头元素
    if(_wakeFlag)
    {
        ElemType ret = _que.front();//获取队头元素作为返回值
        _que.pop();//消费
        _notFull.notify_one();//唤醒
        return ret;
    }
    else
    {
        return nullptr;
    }
}

bool TaskQueue::empty() const
{
    return _que.size() == 0;
}

bool TaskQueue::full() const
{
    return _que.size() == _capacity;
}

void TaskQueue::wakeup()//唤醒所有线程
{
    _wakeFlag = false;
    _notEmpty.notify_all();
}
